home *** CD-ROM | disk | FTP | other *** search
-
- /* xlmath - xlisp builtin arithmetic functions */
-
- #ifdef CI_86
- #include "a:stdio.h"
- #include "xlisp.h"
- #endif
-
- #ifdef AZTEC
- #include "a:stdio.h"
- #include "xlisp.h"
- #endif
-
- #ifdef unix
- #include <stdio.h>
- #include <xlisp.h>
- #endif
-
-
- /* external variables */
-
- extern struct node *xlstack;
-
-
- /* local variables */
-
- static struct node *true;
-
-
- /* forward declarations (the extern hack is for decusc) */
-
- extern struct node *iarith();
- extern struct node *compare();
-
-
- /* Comparison operator defines */
-
- #define lss_op 1
- #define leq_op 2
- #define eql_op 3
- #define neq_op 4
- #define geq_op 5
- #define gtr_op 6
-
- #define sign(n) (((n)<0) ? -1 : (((n)>0) ? 1 : 0))
-
-
- /****************************************
- * add - builtin function for addition *
- ****************************************/
-
- static struct node *add(args)
- struct node *args;
- {
- return iarith(args,'+');
- }
-
-
- /*******************************************
- * sub - builtin function for subtraction *
- *******************************************/
-
- static struct node *sub(args)
- struct node *args;
- {
- return iarith(args,'-');
- }
-
-
- /**********************************************
- * mul - builtin function for multiplication *
- **********************************************/
-
- static struct node *mul(args)
- struct node *args;
- {
- return iarith(args,'*');
- }
-
-
- /****************************************
- * div - builtin function for division *
- ****************************************/
-
- static struct node *div(args)
- struct node *args;
- {
- return iarith(args,'/');
- }
-
-
- /***************************************
- * mod - builtin function for modulus *
- ***************************************/
-
- static struct node *mod(args)
- struct node *args;
- {
- return iarith(args,'%');
- }
-
-
- /***************************************
- * min - builtin function for minimum *
- ***************************************/
-
- static struct node *min(args)
- struct node *args;
- {
- return iarith(args,'m');
- }
-
-
- /***************************************
- * max - builtin function for maximum *
- ***************************************/
-
- static struct node *max(args)
- struct node *args;
- {
- return iarith(args,'M');
- }
-
-
- /***************************************
- * and - builtin function for modulus *
- ***************************************/
-
- static struct node *and(args)
- struct node *args;
- {
- return iarith(args,'&');
- }
-
-
- /**************************************
- * or - builtin function for modulus *
- **************************************/
-
- static struct node *or(args)
- struct node *args;
- {
- return iarith(args,'|');
- }
-
-
- /**********************
- * not - bitwise not *
- **********************/
-
- static struct node *not(args)
- struct node *args;
- {
- struct node *rval;
- int val;
-
- val = xlevmatch(INT,&args)->n_int; /* Evaluate the argument */
- xllastarg(args);
-
- rval = newnode(INT);
- rval->n_int = ~val;
- return (rval);
- }
-
-
- /*************************
- * abs - absolute value *
- *************************/
-
- static struct node *abs(args)
- struct node *args;
- {
- struct node *rval, *argp;
-
- switch (gettype(argp = xlevarg(&args)))
- {
- case INT:
- xllastarg(args);
- rval = newnode(INT);
- if ((rval->n_int = argp->n_int) < 0)
- rval->n_int *= -1;
- break;
-
- #ifdef REALS
- case REAL:
- xllastarg(args);
- rval = newnode(REAL);
- if ((rval->n_real = argp->n_real) < 0)
- rval->n_real *= -1;
- break;
- #endif
-
- default:
- xlfail("bad argument type");
- }
-
- return (rval);
- }
-
-
- #ifdef REALS
-
- /****************************
- * fix - integer from real *
- ****************************/
-
- static struct node *fix(args)
- struct node *args;
- {
- struct node *rval, *argp;
-
- switch (gettype(argp = xlevarg(&args)))
- {
- case INT:
- xllastarg(args);
- rval = newnode(INT);
- rval->n_int = argp->n_int;
- break;
-
- case REAL:
- xllastarg(args);
- rval = newnode(INT);
- rval->n_int = (int) argp->n_real;
- break;
-
- default:
- xlfail("bad argument type");
- }
-
- return (rval);
- }
-
-
- /******************************
- * float - real from integer *
- ******************************/
-
- static struct node *lfloat(args)
- struct node *args;
- {
- struct node *rval, *argp;
-
- switch (gettype(argp = xlevarg(&args)))
- {
- case INT:
- xllastarg(args);
- rval = newnode(REAL);
- rval->n_real = argp->n_int;
- break;
-
- case REAL:
- xllastarg(args);
- rval = newnode(REAL);
- rval->n_real = argp->n_real;
- break;
-
- default:
- xlfail("bad argument type");
- }
-
- return (rval);
- }
-
-
- /*************************************************
- * farith - common floating arithmetic function *
- *************************************************/
-
- static struct node *farith(ival, oldstk, arg, val, ifunct, funct)
- struct node *oldstk, *arg, *val;
- int ival;
- char ifunct, funct;
- {
- struct node *rval;
- long float rslt = (long float) ival, arg_val;
- int arg_typ = REAL;
-
- while(1)
- {
- if (arg_typ == INT)
- arg_val = (long float) (val->n_ptr)->n_int;
- else
- if (arg_typ == REAL)
- arg_val = (val->n_ptr)->n_real;
- else
- xlfail("bad argument type");
-
- switch (ifunct)
- {
- case '+':
- rslt += arg_val;
- break;
-
- case '-':
- rslt -= arg_val;
- break;
-
- case '*':
- rslt *= arg_val;
- break;
-
- case '/':
- rslt /= arg_val;
- break;
-
- case '%':
- case '&':
- case '|':
- xlfail("bad argument type");
-
- case 'm':
- if (rslt > arg_val)
- rslt = arg_val;
- break;
-
- case 'M':
- if (rslt < arg_val)
- rslt = arg_val;
- break;
- }
-
- ifunct = funct;
-
- if (arg->n_ptr == NULL)
- break;
-
- arg_typ = gettype((val->n_ptr = xlevarg(&(arg->n_ptr))));
- }
-
- rval = newnode(REAL);
- rval->n_real = rslt;
-
- xlstack = oldstk;
- return (rval);
- }
- #endif
-
-
- /***************************************
- * arith - common arithmetic function *
- ***************************************/
-
- static struct node *iarith(args,funct)
- struct node *args;
- char funct;
- {
- struct node *oldstk,arg,val,*rval;
- int rslt, arg_val;
-
- oldstk = xlsave(&arg,&val,NULL); /* Create a new stack frame */
-
- arg.n_ptr = args; /* Get first parameter */
-
- arg_val = gettype((val.n_ptr = xlevarg(&arg.n_ptr)));
-
- #ifdef REALS
- if (arg_val == REAL)
- return farith(0, oldstk, &arg, &val, '+', funct);
- #endif
-
- if (arg_val != INT)
- xlfail("bad argument type");
-
- rslt = val.n_ptr->n_int;
-
- while (arg.n_ptr != NULL)
- {
- arg_val = gettype((val.n_ptr = xlevarg(&arg.n_ptr)));
-
- #ifdef REALS
- if (arg_val == REAL)
- return farith(rslt, oldstk, &arg, &val, funct, funct);
- #endif
-
- if (arg_val != INT)
- xlfail("bad argument type");
-
- arg_val = val.n_ptr->n_int;
-
- switch (funct)
- {
- case '+':
- rslt += arg_val;
- break;
-
- case '-':
- rslt -= arg_val;
- break;
-
- case '*':
- rslt *= arg_val;
- break;
-
- case '/':
- rslt /= arg_val;
- break;
-
- case '%':
- rslt %= arg_val;
- break;
-
- case '&':
- rslt &= arg_val;
- break;
-
- case '|':
- rslt |= arg_val;
- break;
-
- case 'm':
- if (rslt > arg_val)
- rslt = arg_val;
- break;
-
- case 'M':
- if (rslt < arg_val)
- rslt = arg_val;
- break;
- }
- }
-
- rval = newnode(INT);
- rval->n_int = rslt;
-
- xlstack = oldstk;
- return (rval);
- }
-
-
- /***********************
- * land - logical and *
- ***********************/
-
- static struct node *land(args)
- struct node *args;
- {
- struct node *oldstk,arg,*val;
-
- oldstk = xlsave(&arg,NULL);
- arg.n_ptr = args;
- val = true;
-
- while (arg.n_ptr != NULL)
- if (xlevarg(&arg.n_ptr) == NULL)
- {
- val = NULL;
- break;
- }
-
- xlstack = oldstk;
- return (val);
- }
-
-
- /*********************
- * lor - logical or *
- *********************/
-
- static struct node *lor(args)
- struct node *args;
- {
- struct node *oldstk,arg,*val;
-
- oldstk = xlsave(&arg,NULL);
- arg.n_ptr = args;
- val = NULL;
-
- while (arg.n_ptr != NULL)
- if (xlevarg(&arg.n_ptr) != NULL)
- {
- val = true;
- break;
- }
-
- xlstack = oldstk;
- return (val);
- }
-
-
- /***********************
- * lnot - logical not *
- ***********************/
-
- static struct node *lnot(args)
- struct node *args;
- {
- struct node *val;
-
- val = xlevarg(&args);
- xllastarg(args);
-
- if (val == NULL)
- return (true);
- else
- return (NULL);
- }
-
-
- /*********************************
- * lss - builtin function for < *
- *********************************/
-
- static struct node *lss(args)
- struct node *args;
- {
- return (compare(args,lss_op));
- }
-
-
- /**********************************
- * leq - builtin function for <= *
- **********************************/
-
- static struct node *leq(args)
- struct node *args;
- {
- return (compare(args,leq_op));
- }
-
-
- /**********************************
- * eql - builtin function for == *
- **********************************/
-
- static struct node *eql(args)
- struct node *args;
- {
- return (compare(args,eql_op));
- }
-
-
- /**********************************
- * neq - builtin function for != *
- **********************************/
-
- static struct node *neq(args)
- struct node *args;
- {
- return (compare(args,neq_op));
- }
-
-
- /**********************************
- * geq - builtin function for >= *
- **********************************/
-
- static struct node *geq(args)
- struct node *args;
- {
- return (compare(args,geq_op));
- }
-
-
- /*********************************
- * gtr - builtin function for > *
- *********************************/
-
- static struct node *gtr(args)
- struct node *args;
- {
- return (compare(args,gtr_op));
- }
-
-
- /**************************************
- * compare - common compare function *
- **************************************/
-
- static struct node *compare(args,funct)
- struct node *args;
- int funct;
- {
- struct node *oldstk,arg,arg1,arg2;
- int type1,type2,cmp;
-
- oldstk = xlsave(&arg,&arg1,&arg2,NULL);
- arg.n_ptr = args;
-
- type1 = gettype(arg1.n_ptr = xlevarg(&arg.n_ptr));
- type2 = gettype(arg2.n_ptr = xlevarg(&arg.n_ptr));
- xllastarg(arg.n_ptr);
-
- if ((type1 == STR) && (type2 == STR))
- cmp = strcmp(arg1.n_ptr->n_str,arg2.n_ptr->n_str);
- else
-
- #ifdef REALS
- if (type1 == INT)
- {
- if (type2 == INT)
- cmp = sign(arg1.n_ptr->n_int - arg2.n_ptr->n_int);
- else
-
- if (type2 == REAL)
- cmp = sign(arg1.n_ptr->n_int - arg2.n_ptr->n_real);
- else
- cmp = arg1.n_ptr - arg2.n_ptr;
- }
- else
-
- if (type1 == REAL)
- {
- if (type2 == INT)
- cmp = sign(arg1.n_ptr->n_real - arg2.n_ptr->n_int);
- else
-
- if (type2 == REAL)
- cmp = sign(arg1.n_ptr->n_real - arg2.n_ptr->n_real);
- else
- cmp = arg1.n_ptr - arg2.n_ptr;
- }
- #else
-
- if ((type1 == INT) && (type2 == INT))
- cmp = sign(arg1.n_ptr->n_int - arg2.n_ptr->n_int);
- #endif
-
- else
- cmp = arg1.n_ptr - arg2.n_ptr;
-
- xlstack = oldstk;
-
- switch (funct)
- {
- case lss_op:
- return (cmp < 0) ? true : NULL;
-
- case leq_op:
- return (cmp <= 0) ? true : NULL;
-
- case eql_op:
- return (cmp == 0) ? true : NULL;
-
- case neq_op:
- return (cmp != 0) ? true : NULL;
-
- case geq_op:
- return (cmp >= 0) ? true : NULL;
-
- case gtr_op:
- return (cmp > 0) ? true : NULL;
-
- }
- xlfail("bad compare operator");
- }
-
-
- /*********************************************
- * gettype - return the type of an argument *
- *********************************************/
-
- static int gettype(arg)
- struct node *arg;
- {
- if (arg == NULL)
- return (LIST);
- else
- return (arg->n_type);
- }
-
-
- /************************************************
- * xlminit - xlisp math initialization routine *
- ************************************************/
-
- xlminit()
- {
- xlsubr("+",add);
- xlsubr("-",sub);
- xlsubr("*",mul);
- xlsubr("/",div);
- xlsubr("%",mod);
- xlsubr("&",and);
- xlsubr("|",or);
- xlsubr("~",not);
- xlsubr("<",lss);
- xlsubr("<=",leq);
- xlsubr("==",eql);
- xlsubr("!=",neq);
- xlsubr(">=",geq);
- xlsubr(">",gtr);
- xlsubr("&&",land);
- xlsubr("||",lor);
- xlsubr("!",lnot);
- xlsubr("min",min);
- xlsubr("max",max);
- xlsubr("abs",abs);
-
- #ifdef REALS
- xlsubr("fix",fix);
- xlsubr("float",lfloat);
- #endif
-
- true = xlenter("t");
- true->n_symvalue = true;
- }